package com.bot.telegramvariousbot.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class DateUtil {

    /**
     * 日期格式，年月日，例如：20050630，20080808
     */
    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";

	/**
	 * date类型转换为String类型 formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
	 * 
	 * @param data
	 *            Date类型的时间
	 * @param formatType
	 * @return
	 */
	public static String dateToString(Date data, String formatType) {
		return new SimpleDateFormat(formatType).format(data);
	}

	/**
	 * long类型转换为String类型
	 * 
	 * @param
	 * @param formatType
	 *            要转换的string类型的时间格式
	 * @return
	 * @throws ParseException
	 */
	public static String longToString(long currentTime, String formatType) throws ParseException {
		Date date = longToDate(currentTime, formatType); // long类型转成Date类型
		String strTime = dateToString(date, formatType); // date类型转成String
		return strTime;
	}

	/**
	 * string类型转换为date类型
	 * 
	 * @param strTime
	 *            要转换的string类型的时间
	 * @param formatType
	 *            要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
	 *            strTime的时间格式必须要与formatType的时间格式相同
	 * @return
	 * @throws ParseException
	 */
	public static Date stringToDate(String strTime, String formatType) throws ParseException {
		SimpleDateFormat formatter = new SimpleDateFormat(formatType);
		Date date = null;
		date = formatter.parse(strTime);
		return date;
	}

	/**
	 * long转换为Date类型
	 * 
	 * @param currentTime
	 *            要转换的long类型的时间
	 * @param formatType
	 *            要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
	 * @return
	 * @throws ParseException
	 */
	public static Date longToDate(long currentTime, String formatType) throws ParseException {
		if (formatType == null) {
			formatType = "yyyy-MM-dd HH:mm:ss";
		}
		Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
		String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
		Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
		return date;
	}

	/**
	 * string类型转换为long类型
	 * 
	 * @param strTime
	 *            要转换的String类型的时间
	 * @param formatType
	 *            时间格式 strTime的时间格式和formatType的时间格式必须相同
	 * @return
	 * @throws ParseException
	 */
	public static long stringToLong(String strTime, String formatType) throws ParseException {
		Date date = stringToDate(strTime, formatType); // String类型转成date类型
		if (date == null) {
			return 0;
		} else {
			long currentTime = dateToLong(date); // date类型转成long类型
			return currentTime;
		}
	}

	/**
	 * date类型转换为long类型
	 * 
	 * @param date
	 *            要转换的date类型的时间
	 * @return
	 */
	public static long dateToLong(Date date) {
		return date.getTime();
	}

	/**
	 * 获取当天0点
	 * 
	 * @return
	 */
	public static Date getTimesMorning() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 获取当天24点
	 * 
	 * @return
	 */
	public static Date getTimesNight() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 24);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 获取某一个时间某一个月的同一个时间
	 * 
	 * @param monthlyTime
	 *            月数
	 * @return
	 */
	public static Date getSameDayOfMonth(Date date, Integer monthlyTime) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, +monthlyTime.intValue());
		return cal.getTime();
	}

	/**
	 * 获取某一个时间某一个月的同一个时间
	 * 
	 * @param date day
	 *            月数
	 * @return
	 */
	public static Date getSameDayOfDay(Date date, Integer day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, +day.intValue());
		return cal.getTime();
	}
	/**
	 * 时期相减得到天数
	 */
	public static long getDaySub(String beginDateStr, String endDateStr)
    {
        long day=0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate;
        Date endDate;
        try
        {
            beginDate = format.parse(beginDateStr);
            endDate= format.parse(endDateStr);    
            day=(endDate.getTime()-beginDate.getTime())/(24*60*60*1000);    
            //System.out.println("相隔的天数="+day);   
        } catch (ParseException e)
        {
            // TODO 自动生成 catch 块
            e.printStackTrace();
        }   
        return day;
    }
	/**
	 * 时期相减得到天数
	 */
	public static long getDaySub(long beginDate, long endDate)
	{
		long day=(endDate-beginDate)/(24*60*60*1000);
		return day;
	}
    /*
     * @Author zhou
     * @Description 当天时间最后毫秒数
     * @Date 13:40 2018/9/15
     * @Param [current]
     * @return long
     **/
	public static long getLongOfDayEnd(long current){
		if(current==0L){
			return 0L;
		}
		long zero = getLongOfDayStart(current);
		long end=zero+1000L*3600L*24L;
		return end;
	}
	/*
	 * @Author zhou
	 * @Description 当天时间开始毫秒数
	 * @Date 11:17 2018/9/25
	 * @Param [current]
	 * @return long
	 **/
	public static long getLongOfDayStart(long current){
		if(current==0L){
			return 0L;
		}
		TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
		Calendar calendar = Calendar.getInstance(curTimeZone);
		calendar.setTimeInMillis(current);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	/**
	 * 查询当前日期前(后)x天的日期
	 *
	 * @param millis 当前日期毫秒数
	 * @param day 天数（如果day数为负数,说明是此日期前的天数）
	 * @return long 毫秒数只显示到天，时间全为0
	 * @throws ParseException
	 */
	public static long beforDateNum(long millis, int day) throws ParseException {
        if(millis==0L){
            return 0L;
        }
        TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
        Calendar calendar = Calendar.getInstance(curTimeZone);
        calendar.setTimeInMillis(millis);
        calendar.add(Calendar.DAY_OF_YEAR, day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
	}
	public static long getCouponDeadlinetime(long current ,int day){
		long currentEnd=getLongOfDayEnd(current);
		long lday= (long)day;
		long dayTime=lday*3600L * 1000L * 24L;
		return currentEnd + dayTime -1000L;
	};


	public static long getLongOfDayStartFail(long current){
		long zero = current/(1000*3600*24)*(1000*3600*24) - TimeZone.getDefault().getRawOffset();
		return zero;
	}

	public static final int SECONDS_IN_DAY = 60 * 60 * 24;
	public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;
	
	/** 
	 * @Description //判断两个时间的毫秒数是不是同一天的
	 * @Author CHENCHUN
	 * @Date 17:31 2018/11/30
	*/ 
	public static boolean isSameDayOfMillis(final long ms1, final long ms2) {
		final long interval = ms1 - ms2;
		return interval < MILLIS_IN_DAY
				&& interval > -1L * MILLIS_IN_DAY
				&& toDay(ms1) == toDay(ms2);
	}

    /**
     * 格式化Date时间为推送英文格式
     *
     * @param time Date类型时间
     * @param
     * @return 格式化后的字符串 15:25 UTC on August 25, 2021
     */
    public static String parseDateToPushEnStr(Date time) {
    	//15:25 UTC on August 25, 2021
		SimpleDateFormat mFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
		String m=mFormat.format(time);
		SimpleDateFormat dFormat = new SimpleDateFormat("MMM d,yyyy ", Locale.ENGLISH);
		String d=dFormat.format(time);
        return m+" UTC on "+d;
    }

	public static String parseDateToTGEnStr(Date time) {
		//15:25 PM UTC on August 25, 2021
		SimpleDateFormat mFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
		String m=mFormat.format(time);
		SimpleDateFormat dFormat = new SimpleDateFormat("MMM d,yyyy ", Locale.ENGLISH);
		String d=dFormat.format(time);
		return m+" UTC on "+d;
	}

	private static long toDay(long millis) {
		return (millis + TimeZone.getDefault().getOffset(millis)) / MILLIS_IN_DAY;
	}


	public static String dateToEnString(Date data, String formatType) {
		return new SimpleDateFormat(formatType).format(data);
	}

	public static void main(String[] args) throws Exception{

	/*	System.out.println(getCouponDeadlinetime(System.currentTimeMillis(),30));
		System.out.println(getLongOfDayStart(1540310480000l));
		System.out.println(getLongOfDayEnd(0l));
		System.out.println(getLongOfDayEnd(1540386020000l)-getLongOfDayStart(1540310480000l));*/
//        Date timesMorning = getTimesMorning();
//        Date timesNight = getTimesNight();
//        System.out.println(timesMorning.getTime()-86400000L);
//        System.out.println(timesNight.getTime()-86400000L);
//		System.out.println(longToString(System.currentTimeMillis(),"yyyy-MM-dd "));
		//System.out.println(getDaySub(1574179199000L,1574221777000L));
		//System.out.println(beforDateNum(System.currentTimeMillis(),2));

		LocalDateTime date = LocalDateTime.now(ZoneOffset.of("-02:30"));

		LocalDateTime localDateTime = LocalDateTime.now();
		ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneOffset.of("-02:30"));

		//15:25 UTC on August 25, 2021
		Date toady = new Date();
		System.out.println(parseDateToPushEnStr(toady));

		System.out.println(parseDateToPushEnStr(new Date()));


		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);
		System.out.println(dateFormat.format(new Date()));
		dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
		System.out.println(dateFormat.format(new Date()));
		dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
		System.out.println(dateFormat.format(new Date()));
		dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
		System.out.println(dateFormat.format(new Date()));
		dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
		System.out.println(dateFormat.format(new Date()));
	}

}
